使用函式庫,若能暸解內部操控 DOM 的原則與細節,你可以寫出更快更好的程式,或者是在自己的程式裡運用那些技巧。
<div id="one">one</div>
var d1 = document.getElementById('one');
d1.insertAdjacentHTML('afterend', '<div id="two">two</div>');
// At this point, the new structure is:
// <div id="one">one</div><div id="two">two</div>
//確保自我結束元素可被正常解析
var tags = /^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i;
function convert(html) {
return html.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag) {
return tags.test(tag) ?
all :
front + "></" + tag + ">";
})
}
console.log(convert("<a/>" === "<a></a>"))
//從某 HTML 字串產生 DOM 節點
function getNodes(htmlString, doc) {
var map = {
"<td":[3,"<table><tbody><tr>", "</tr></tbody></table>"],
"<th":[3,"<table><tbody><tr>", "</tr></tbody></table>"],
"<tr":[2,"<table><thead>", "</thead></table>"]
}
var tagName = htmlString.match(/<\w+/),
mapEntry = tagName ? map[tagName[0]] : null;
if(!mapEntry) mapEntry = [0, " ", " " ];
var div = (doc || document).createElement("div");
div.innerHTML = mapEntry[1] + htmlString + mapEntry[2];
while(mapEntry[0]--) div = div.lastChild;
return div.childNodes;
}
getNodes("<td>test</td><td>test2</td>") //NodeList(2) [td, td]
function getNodes(htmlString, doc, fragment) {
var map = {
"<td":[3,"<table><tbody><tr>", "</tr></tbody></table>"],
"<th":[3,"<table><tbody><tr>", "</tr></tbody></table>"],
"<tr":[2,"<table><thead>", "</thead></table>"]
}
console.log(htmlString)
var tagName = htmlString.match(/<\w+/),
mapEntry = tagName ? map[tagName[0]] : null;
if(!mapEntry) mapEntry = [0, " ", " " ];
var div = (doc || document).createElement("div");
div.innerHTML = mapEntry[1] + htmlString + mapEntry[2];
while(mapEntry[0]--) div = div.lastChild;
if(fragment) {
while(div.firstChild) {
fragment.appendChild(div.firstChild)
}
}
return div.childNodes;
}
function root(elem, cur) {
return elem.nodeName.toLowerCase() === "table" && cur.nodeName.toLowerCase() === "tr" ? (elem.getElementsByTagName("tbody")[0] || elem.appendChild(elem.ownerDocument.createElement("tbody"))) : elem;
}
window.onload = function(){
function insert(elems, args, callback) {
if(elems.length) {
var doc = elems[0].ownerDocument || elems[0],
fragment = doc.createDocumentFragment(),
scripts = getNodes(args[0], doc, fragment),
first = fragment.firstChild;
if(first) {
for (var i = 0; elems[i]; i++) {
callback.call(root(elems[i], first), i > 0 ? fragment.cloneNode(true) : fragment);
}
}
}
}
var divs = document.getElementsByTagName("div");
insert(divs, ["<b>First</b>"], function (fragment) { this.appendChild(fragment) })
}
//jQuery 部分實作,無法執行
function globalEval(data) {
data = data.replace(/^\s+|\s+$/g, "");
if(data) {
var head = document.getElementsByTagName("head")[0] || document.documentElement,
script = document.createElement("script");
script.type = "text/javascript";
script.text = data;
head.insertBefore(script, head.firstChild);
head.removeChild(script);
}
}
https://developer.mozilla.org/zh-TW/docs/Web/API/Element/insertAdjacentHTML
https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment